package archer.framework.utils;

import jodd.datetime.JDateTime;

import java.sql.Timestamp;
import java.util.Calendar;
import java.util.Date;

/**
 * 日期处理工具类
 *
 * @author christ
 * @date 2016/3/31
 */
public class DateProcessor {

    private JDateTime date;

    // factory methods

    public static DateProcessor now() {
        return today();
    }

    public static DateProcessor today() {
        return date(new JDateTime());
    }

    public static DateProcessor date(Date date) {
        return date(new JDateTime(date));
    }

    public static DateProcessor date(String date) {
        return date(new JDateTime(date));
    }

    public static DateProcessor date(long millis) {
        return date(new JDateTime(millis));
    }

    public static DateProcessor date(JDateTime date) {
        return new DateProcessor(date);
    }

    protected DateProcessor(JDateTime date) {
        this.date = date;
    }

    /**
     * 某月第一天
     *
     * @return
     */
    public DateProcessor firstDateOfMonth() {
        Calendar c = date.convertToCalendar();
        c.add(Calendar.MONTH, 0);
        c.set(Calendar.DAY_OF_MONTH, 1);
        date = new JDateTime(c.getTime());
        return this;
    }

    /**
     * 某月最后一天
     *
     * @return
     */
    public DateProcessor lastDateOfMonth() {
        Calendar c = date.convertToCalendar();
        c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH));
        date = new JDateTime(c.getTime());
        return this;
    }

    /**
     * 某周第一天（星期天）
     *
     * @return
     */
    public DateProcessor firstDateOfWeek() {
        Calendar c = date.convertToCalendar();
        c.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
        date = new JDateTime(c.getTime());
        return this;
    }

    /**
     * 某周最后一天（星期六）
     *
     * @return
     */
    public DateProcessor lastDateOfWeek() {
        Calendar c = date.convertToCalendar();
        c.set(Calendar.DAY_OF_WEEK, Calendar.SATURDAY);
        date = new JDateTime(c.getTime());
        return this;
    }

    /**
     * 加上几天
     *
     * @param day
     * @return
     */
    public DateProcessor addDay(int day) {
        if (day == 0) {
            return this;
        }

        date = date.addDay(day);
        return this;
    }

    /**
     * 加上几天
     *
     * @param day
     * @param monthFix
     * @return
     */
    public DateProcessor addDay(int day, boolean monthFix) {
        if (day == 0) {
            return this;
        }

        date = date.addDay(day, monthFix);
        return this;
    }

    /**
     * 减去几天
     *
     * @param day
     * @return
     */
    public DateProcessor subDay(int day) {
        if (day == 0) {
            return this;
        }

        date = date.subDay(day);
        return this;
    }

    /**
     * 减去几天
     *
     * @param day
     * @param monthFix
     * @return
     */
    public DateProcessor subDay(int day, boolean monthFix) {
        if (day == 0) {
            return this;
        }

        date = date.subDay(day, monthFix);
        return this;
    }

    /**
     * 加上几周
     *
     * @param week
     * @return
     */
    public DateProcessor addWeek(int week) {
        if (week == 0) {
            return this;
        }

        date = date.addDay(7 * week);
        return this;
    }

    /**
     * 加上几周
     *
     * @param week
     * @param monthFix
     * @return
     */
    public DateProcessor addWeek(int week, boolean monthFix) {
        if (week == 0) {
            return this;
        }

        date = date.addDay(7 * week, monthFix);
        return this;
    }


    /**
     * 减去几周
     *
     * @param week
     * @return
     */
    public DateProcessor subWeek(int week) {
        if (week == 0) {
            return this;
        }

        date = date.subDay(7 * week);
        return this;
    }

    /**
     * 减去几周
     *
     * @param week
     * @param monthFix
     * @return
     */
    public DateProcessor subWeek(int week, boolean monthFix) {
        if (week == 0) {
            return this;
        }

        date = date.subDay(7 * week, monthFix);
        return this;
    }

    /**
     * 减去几个月
     *
     * @param month
     * @return
     */
    public DateProcessor subMonth(int month) {
        date = date.subMonth(month);
        return this;
    }

    /**
     * 减去几个月
     *
     * @param month
     * @param monthFix
     * @return
     */
    public DateProcessor subMonth(int month, boolean monthFix) {
        date = date.subMonth(month, monthFix);
        return this;
    }

    /**
     * 加上几个月
     *
     * @param month
     * @return
     */
    public DateProcessor addMonth(int month) {
        date = date.addMonth(month);
        return this;
    }

    /**
     * 加上几个月
     *
     * @param month
     * @param monthFix
     * @return
     */
    public DateProcessor addMonth(int month, boolean monthFix) {
        date = date.addMonth(month, monthFix);
        return this;
    }


    //--------------------------------------------------------

    public boolean isAfter(DateProcessor date) {
        return this.date.isAfter(date.getJDateTime());
    }

    public boolean isAfter(String date) {
        return isAfter(DateProcessor.date(date));
    }

    public boolean isAfter(Date date) {
        return isAfter(DateProcessor.date(date));
    }

    public boolean isAfter(JDateTime date) {
        return isAfter(DateProcessor.date(date));
    }

    public boolean isAfter(long date) {
        return isAfter(DateProcessor.date(date));
    }

    public boolean isBefore(DateProcessor date) {
        return this.date.isBefore(date.getJDateTime());
    }

    public boolean isBefore(String date) {
        return isBefore(DateProcessor.date(date));
    }

    public boolean isBefore(Date date) {
        return isBefore(DateProcessor.date(date));
    }

    public boolean isBefore(JDateTime date) {
        return isBefore(DateProcessor.date(date));
    }

    public boolean isBefore(long date) {
        return isBefore(DateProcessor.date(date));
    }

    /**
     * 计算日期差
     *
     * @param dateProcessor
     * @return
     */
    public int daysBetween(DateProcessor dateProcessor) {
        return this.getJDateTime().daysBetween(dateProcessor.getJDateTime());
    }

    /**
     * 获得timeMills
     *
     * @return
     */
    public long getTimeInMillis() {
        return this.date.getTimeInMillis();
    }

    /**
     * 获得Date
     *
     * @return
     */
    public Date getDate() {
        return this.date.convertToDate();
    }

    /**
     * 获得timestamp
     *
     * @return
     */
    public Timestamp getTimestamp() {
        return this.date.convertToSqlTimestamp();
    }

    /**
     * 获得JDateTime以供其他处理
     *
     * @return
     */
    public JDateTime getJDateTime() {
        return date;
    }

    /**
     * 转成字符串表示的日期格式
     *
     * @param format
     * @return
     */
    public String toString(String format) {
        return date.toString(format);
    }


    public String dateString() {
        return toString();
    }

    public String dateTimeString() {
        return toString("YYYY-MM-DD hh:mm:ss");
    }

    /**
     * 转成YYYY-MM-DD表示的字符串格式
     *
     * @return
     */
    public String toString() {
        return toString("YYYY-MM-DD");
    }
}
